package gestores;

import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Vector;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.Timer;

import utilidades.WriteTextFile;
import clasesBasicas.Empresa;
import clasesBasicas.Global;
import clasesBasicas.Movimiento;

public class SistemaEmpresas {

	String[] empresasIbex = {"Abertis","Acciona","Acs","AmadeusItHold-a-","ArcelormittalReg","BancoSabadell","BancoSantander",
			"BankiaSa","Bankinter","Bbva","BcoPopularEspanol","BolsasYMercados","Caixabank","Dia","EbroFoods","Enagas","Ferrovial",
			"FomentoConstr.","Gamesa", "GasNaturalSdg","GrifolsA","Iberdrola","Inditex","IndraSistemas-a-","Intl.Cons.AirGrp","Jazztel","Mapfre","MediasetEspana",
			"Ohl","RedElectricaCorp","Repsol","Sacyr","TecnicasReunidas","Telefonica","Viscofan"};

	Vector<Empresa> listaEmpresas=null;
	String ultimaActualización=null;
	public ArrayList<Movimiento> misMovimientos = null;
	public static int contador=0;
	public static Connection conexion;
	private boolean primeraVez=true;
	
	/*
	 * Constructor, crea la conexión y un hilo con temporizador para actualizar
	 */
	public SistemaEmpresas() throws Exception
	{
		System.out.println("Primera vez: "+contador);
		contador++;
		listaEmpresas= new Vector<Empresa>(35);
		misMovimientos = new ArrayList<Movimiento>();
		obtenerConexion();
		//Pongo un temporizador, cada 15 minutos actualiza los datos
		Timer temporizador= new Timer(180000, new ActionListener(){

			public void actionPerformed(ActionEvent e) {

				try {

					activarActualizaciones();
				} catch (Exception e1) {
					e1.printStackTrace();
					JOptionPane.showMessageDialog(null, "No se ha podido actualizar el programa. Compruebe su conexión a internet.", "Error al actualizar", JOptionPane.ERROR_MESSAGE, new ImageIcon());
				}
			}			

		});
		temporizador.start();
		System.out.println("Segunda para empezar.");
		this.activarActualizaciones();
		System.out.println("Aqui");

	}

	/*
	public static void main (String[]args) throws Exception	{

		SistemaEmpresas sistemaPrincipal= new SistemaEmpresas();

		while(sistemaPrincipal.listaEmpresas==null)
		{
			System.out.println("Sigo aqui"); //espera hasta que actualice la lista
		}

		if(sistemaPrincipal.listaEmpresas!=null)
		{
			sistemaPrincipal.mostrarEmpresasIbex();
		}

		//Prueba
		sistemaPrincipal.datosEstadisticas("01/05/14 00:00:00", "02/05/14 23:59:00", 1);

		//System.out.println("eee");

	}
	 */

	/*
	 * Consulta a la BD las transacciones de un usuario y las guarda en lista de movimientos
	 */
	public void actualizarMisMovimientos() throws SQLException{
		misMovimientos.clear();
		String sql="SELECT * FROM TRANSACCION WHERE DNI = " + Global.sU.usuarioActual.getDni();
		ResultSet resultado = null; 
		Statement sentencia= null;

		try {  
			sentencia = getConexion().createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
			resultado = sentencia.executeQuery(sql); 

		} catch (SQLException e) { 
			e.printStackTrace(); 
		}
		while(resultado.next())
		{
			Movimiento mov = new Movimiento(resultado.getInt("COD_EMPRESA"), resultado.getTimestamp("FECHA"), 
					resultado.getString("TIPO_TRANSACCION").charAt(0), resultado.getInt("CANTIDAD"), 
					resultado.getDouble("PRECIO"));
			misMovimientos.add(mov);
		}

		resultado.close();
		sentencia.close();
	}

	/*
	private void mostrarEmpresasIbex() {

		for(int i=0;i<empresasIbex.length;i++)
		{
			Empresa temp=listaEmpresas.get(i);
			//temp.mostrar();
			//System.out.println(i);
		}
	}
	 */

	/*
	 * Actualiza las empresas 
	 */
	private void activarActualizaciones() throws Exception {
		
		System.out.println(" \n Aqui he pasado por ahora<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
		String sql="SELECT * FROM EMPRESA ORDER BY COD_EMPRESA";
		ResultSet resultado = null; 
		Statement sentencia= null;

		try {  
			sentencia = getConexion().createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
			resultado = sentencia.executeQuery(sql); 

		} catch (SQLException e) { 
			e.printStackTrace(); 
		}

		if(listaEmpresas.isEmpty())
		{

			while(resultado.next())
			{
				Empresa temp=new Empresa(resultado.getInt("COD_EMPRESA"), resultado.getString("NOMBRE_EMP"), resultado.getString("DESCRIPCION"), resultado.getDouble("ULTIMO"), resultado.getDouble("DIFERENCIA"), resultado.getDouble("VOLUMEN"), resultado.getDouble("MAX_DIARIO"), resultado.getDouble("MIN_DIARIO"));
				listaEmpresas.add(temp);
			}
		}
		else
		{
			//mirar si cambia el valor
			int contador=0;
			while(resultado.next())
			{

				Empresa temp=listaEmpresas.get(contador);

				if(resultado.getDouble("ULTIMO")!=temp.getUltimo() || resultado.getDouble("DIFERENCIA")!=temp.getDiferencia() || resultado.getDouble("VOLUMEN")!=temp.getVolumen() || resultado.getDouble("MAX_DIARIO")!=temp.getMaximo() || resultado.getDouble("MIN_DIARIO")!=temp.getMinimo())
				{
					//si la fecha es más nueva que la anterior actualiza
					temp.setUltimo(resultado.getDouble("ULTIMO")); temp.setDiferencia(resultado.getDouble("DIFERENCIA")); temp.setVolumen(resultado.getDouble("VOLUMEN")); temp.setMaximo(resultado.getDouble("MAX_DIARIO")); temp.setMinimo(resultado.getDouble("MIN_DIARIO"));

					contador++;
				}
				else
				{
					contador++;
				}
			}
		}
		
		resultado.close();
		sentencia.close();
		System.out.println("------------------------------------------->>>>>>>>>>>>>>aQUI SEGURO");
		if(!primeraVez)
		{
			System.out.println("------------------------------------------->>>>>>>>>>>>>>aQUI");
			Global.frame.actualizar();
		}
		else
		{
			primeraVez=false;
		}
	}
	/*
	 * Gets y Sets
	 */

	/*
	private Empresa getEmpresa(String nombre)
	{	
		Empresa temp = null;
		for(int i=0;i<listaEmpresas.size();i++)
		{
			temp= listaEmpresas.get(i);
			if(temp.getNombre().equalsIgnoreCase(nombre))
			{
				break;
			}
		}
		return temp;
	}
	 */
	public Empresa getEmpresa(int cod_Emp)
	{	
		Empresa temp = null;
		for(int i=0;i<listaEmpresas.size();i++)
		{
			temp= listaEmpresas.get(i);
			if(temp.getCodigo()==cod_Emp)
			{
				break;
			}
		}
		return temp;
	}


	public Vector<Empresa> getListaEmpresas() {
		return listaEmpresas;
	}

	public  Vector<Empresa> getLista()
	{
		return listaEmpresas;
	}
	/*
	private int obtenerCodigo(String nombre)
	{
		int i;
		for(i=0;i<empresasIbex.length;i++)
		{
			if(empresasIbex[i].equalsIgnoreCase(nombre))
			{
				break;
			}
		}
		return i+1;
	}
	 */

	/*
	 * Crea la conexion
	 */
	private void obtenerConexion()
	{
		//System.out.println("AQUIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII");
		try { 
			Class.forName("oracle.jdbc.OracleDriver"); 
			String BaseDeDatos = "jdbc:oracle:thin:@bdprog4.no-ip.org:1521:XE";

			conexion = DriverManager.getConnection(BaseDeDatos, "admin","admin"); 

			if (conexion != null) { 
				System.out.println("----------------Conexion exitosa!-------------------"); 
			} else { 
				System.out.println("Conexion fallida!"); 
			} 
		} catch (Exception e) { 
			e.printStackTrace(); 
		}
	}

	public static Connection getConexion() { 
		return conexion; 
	}
	/*
	 * Cosulta la BS y crea fichero con los datos consultados para la creación de estadisticas
	 */
	public void datosEstadisticas(String desde, String hasta, int empresa)
	{
		String sql = "SELECT COD_EMPRESA, FECHA, VALOR FROM VALOR_ACTUAL WHERE FECHA BETWEEN '"+ desde +"' AND '"+hasta+"' AND COD_EMPRESA = "+empresa + "ORDER BY FECHA";
		//hay que poner order by, es acendente  la ordenacion no?
		ResultSet resultado=null;
		Statement sentencia=null;

		try {  
			sentencia = getConexion().createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
			resultado = sentencia.executeQuery(sql); 

		} catch (SQLException e) { 
			e.printStackTrace(); 
		}
		try {
			ArrayList<String>aDatos=new ArrayList<String>();
			while(resultado.next())
			{
				String temp="E"+"\t"+resultado.getTimestamp("FECHA").toString()+"\t"+resultado.getDouble("VALOR")+"\n";					
				aDatos.add(temp);
			}
			System.out.println("aqui si");
			WriteTextFile.write("estadisticas.txt",aDatos);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			resultado.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			sentencia.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}





/*
 * Metodo para la compra de acciones
 * Prec:Dinero disponible=true;
 * 1º Introduce el movimiento de la transacción en la BD
 * 2º Actualiza los valores que posees en la BD y en el sistema
 * 3º Actualiza el dinero actual en la BD y en el sistema
 */
	public int comprarAcciones(int dni, int cod_empresa, int cant, double precioAccion)
	{
		//realizo la compra
		Timestamp ts= new  Timestamp(System.currentTimeMillis());
		//		String sql="INSERT INTO TRANSACCION VALUES ("+dni+", "+cod_empresa+", "+ts.to+", "+"'C', "+cant+", "+precioAccion+")";
		int resultado=-10;

		try {
			PreparedStatement stmt;
			stmt = conexion.prepareStatement("INSERT INTO TRANSACCION VALUES (?,?,?,?,?,?)");
			stmt.setInt(1,dni);
			stmt.setInt(2,cod_empresa);
			stmt.setTimestamp(3,ts);
			stmt.setString(4, "C");
			stmt.setInt(5,cant);
			stmt.setDouble(6,precioAccion);
			resultado=stmt.executeUpdate();
			stmt.close();
			Movimiento tem = new Movimiento(cod_empresa, ts,'C', cant, precioAccion);
			misMovimientos.add(tem);
			System.out.println("insert transaccion");
		} catch (SQLException e2) {
			e2.printStackTrace();

		}
		boolean existe=false;
		if(resultado==1)
		{
			existe=actualizarAccionesEmpresa(dni, cod_empresa);
		}
		if(existe==true)
		{
			int total=gestores.SistemaUsuarios.usuarioActual.getAcciones(cod_empresa)+cant;

			String sql3 = "UPDATE VALORES_PROPIEDAD SET CANTIDAD="+total+"WHERE DNI="+dni+" AND COD_EMPRESA="+cod_empresa;
			//hay que poner order by, es acendente  la ordenacion no?
			ResultSet resultado3=null;
			Statement sentencia3=null;

			try {  
				sentencia3 = getConexion().createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
				resultado3 = sentencia3.executeQuery(sql3); 

				sentencia3.close();
				resultado3.close();

			} catch (SQLException e) { 
				System.out.println("no existe fila todabia de esta empresa"); 
			}
			gestores.SistemaUsuarios.usuarioActual.setAcciones(cod_empresa,total );
		}
		else
		{
			PreparedStatement stmt2;
			try {
				stmt2 = conexion.prepareStatement("INSERT INTO VALORES_PROPIEDAD VALUES (?,?,?)");
				stmt2.setInt(1,dni);
				stmt2.setInt(2,cod_empresa);
				stmt2.setInt(3,cant);
				resultado=stmt2.executeUpdate();
				stmt2.close();
				gestores.SistemaUsuarios.usuarioActual.modDinero(-cant*precioAccion);
			} catch (SQLException e) {
				e.printStackTrace();
				return -1;
			}

		}
		String sql4 = "UPDATE USUARIO SET DINERO_ACTUAL=DINERO_ACTUAL-"+(cant*precioAccion)+" WHERE DNI="+dni;
		//hay que poner order by, es acendente  la ordenacion no?
		System.out.println("paso 0");
		ResultSet resultado4=null;
		Statement sentencia4=null;

		try {  
			System.out.println("paso 1");

			sentencia4 = getConexion().createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
			System.out.println("paso 2");

			resultado4 = sentencia4.executeQuery(sql4); 
			System.out.println("paso 3");

			sentencia4.close();
			System.out.println("paso 4");
			resultado4.close();
			System.out.println("paso 5");
			System.out.println("comra y actualiza dinero actual");
			gestores.SistemaUsuarios.usuarioActual.modDinero(-cant*precioAccion);
		} catch (SQLException e) { 
			e.printStackTrace(); 
		}
		Global.pNorte.actualizarNorteLogueado();
		Global.pEmp.actualizarMaximos();
		return 1;

	}

/*
 * Metodo para la venta de acciones
 * 1º Actualiza los valores que posees en la BD y en el sistema
 * 2º Introduce el movimiento de la transacción en la BD 
 * 3º Actualiza dinero en la BD y en el sistema
 * 4º Actualiza el Ranking en la BD y en el sistema
 */
	public int venderAcciones(int dni, int cod_empresa, int cant, double precioAccion) {

		// TODO Auto-generated method stub
		//realizo la compra

		boolean existe=false;

		existe=Global.sU.actualizarAcciones();//Actualiza todas las acciones
		int cantidadActual=Global.sU.usuarioActual.getAcciones(cod_empresa);
		System.out.println("Tengo :"+cantidadActual+" Y quiero comprar :"+cant);
		if((cantidadActual>=cant)&&(existe==true))
		{
			int restantes=cantidadActual-cant;
			System.out.println("me sobran"+restantes);
			String sql3 = "UPDATE VALORES_PROPIEDAD SET CANTIDAD="+restantes+"WHERE DNI="+dni+" AND COD_EMPRESA="+cod_empresa;
			System.out.println(sql3);
			//hay que poner order by, es acendente  la ordenacion no?
			ResultSet resultado3=null;
			Statement sentencia3=null;

			try {  
				sentencia3 = getConexion().createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
				resultado3 = sentencia3.executeQuery(sql3); 

				sentencia3.close();
				resultado3.close();
				gestores.SistemaUsuarios.usuarioActual.modDinero(cant*precioAccion);


			} catch (SQLException e) { 

				e.printStackTrace(); 
			}

			Timestamp ts= new  Timestamp(System.currentTimeMillis());

			try {
				PreparedStatement stmt;
				stmt = conexion.prepareStatement("INSERT INTO TRANSACCION VALUES (?,?,?,?,?,?)");
				stmt.setInt(1,dni);
				stmt.setInt(2,cod_empresa);
				stmt.setTimestamp(3,ts);
				stmt.setString(4, "V");
				stmt.setInt(5,cant);
				stmt.setDouble(6,precioAccion);
				stmt.executeUpdate();
				stmt.close();
				Movimiento tem = new Movimiento(cod_empresa, ts,'V', cant, precioAccion);
				misMovimientos.add(tem);
			} catch (SQLException e2) {
				e2.printStackTrace();

			}
			String sql4 = "UPDATE USUARIO SET DINERO_ACTUAL=DINERO_ACTUAL+"+(cant*precioAccion)+" WHERE DNI="+dni;
			//hay que poner order by, es acendente  la ordenacion no?
			ResultSet resultado4=null;
			Statement sentencia4=null;

			try {  
				sentencia4 = getConexion().createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
				resultado4 = sentencia4.executeQuery(sql4); 
				sentencia4.close();
				resultado4.close();
				System.out.println("vende y actualiza dinero actual");
			}catch( Exception e)
			{
				e.printStackTrace();
			}
			String sql5 = "UPDATE RANKING SET PUNTUACION = PUNTUACION +"+((int)cant*precioAccion)+" WHERE ID_USUARIO ='" + Global.sU.usuarioActual.getId_usuario()+"'";
			System.out.println(sql5);
			//hay que poner order by, es acendente  la ordenacion no?
			ResultSet resultado5=null;
			Statement sentencia5=null;

			try {  
				sentencia5 = getConexion().createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
				resultado5 = sentencia5.executeQuery(sql5); 
				sentencia5.close();
				resultado5.close();
				System.out.println("actualiza puntos");
			}catch( Exception e)
			{
				e.printStackTrace();
			}
			Global.pNorte.actualizarNorteLogueado();
			Global.pEmp.actualizarMaximos();
			return 0;
		}


		return -1;
	}
/*
 * Metodo para consultar la BD y guardar cuantas acciones se posee de cada empresa 
 */
	public static boolean actualizarAccionesEmpresa(int dni, int cod_empresa)
	{
		boolean existe=false;
		PreparedStatement stmt;
		String sql2 = "SELECT * FROM VALORES_PROPIEDAD WHERE DNI="+dni+" AND COD_EMPRESA="+cod_empresa;
		//hay que poner order by, es acendente  la ordenacion no?
		ResultSet resultado2=null;
		Statement sentencia2=null;

		try {  
			sentencia2 = getConexion().createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
			resultado2 = sentencia2.executeQuery(sql2); 
			while(resultado2.next())
			{
				int cantidad=resultado2.getInt(3);
				gestores.SistemaUsuarios.usuarioActual.setAcciones(cod_empresa, cantidad);

				existe=true;
			}
			sentencia2.close();
			resultado2.close();
			System.out.println("select valores_ropiedad");

		} catch (SQLException e) { 
			e.printStackTrace(); 
		}
		return existe;
	}

}